package me.riddhimanadib.formmaster.model;

import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.Pair;
import android.widget.EditText;
import android.widget.Filter;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import me.riddhimanadib.formmaster.R;

/**
 * 表格元素
 */
public class FormElement implements FormObject {

    // different types for the form elements
    public static final int TYPE_EDITTEXT_TEXT_SINGLELINE = 1;
    public static final int TYPE_EDITTEXT_TEXT_MULTILINE = 2;
    public static final int TYPE_EDITTEXT_NUMBER = 3;
    public static final int TYPE_EDITTEXT_EMAIL = 4;
    public static final int TYPE_EDITTEXT_PHONE = 5;
    public static final int TYPE_PICKER_DATE = 6;
    public static final int TYPE_PICKER_TIME = 7;
    public static final int TYPE_PICKER_SINGLE = 8;
    public static final int TYPE_PICKER_MULTI_CHECKBOX = 9;
    public static final int TYPE_EDITTEXT_PASSWORD = 10;
    //// FIXME: 17/10/18 在这里添加类型
    public static final int TYPE_SWITCH = 11;
    public static final int TYPE_RADIOGROUP = 12;
    public static final int TYPE_EDITTEXT_ASSISTANT_BUTTON = 13;
    public static final int TYPE_EMPTY = 14;
    public static final int TYPE_PICKER_DATE_AND_TIME = 15;
    public static final int TYPE_PICKER_SINGLE_WITH_FILTER = 16;
    // private variables
    private int mTag; // unique tag to identify the object
    private int mType; // type for the form element
    private String mTitle; // title to be shown on left
    private String mValue; // value to be shown on right
    private List<String> mOptions; // list of options for single and multi picker
    private List<String> mOptionsSelected; // list of selected options for single and multi picker
    private List<Object> mSpecifiedValues; // list of options for single and multi picker
    private Object mSpecifiedValue; // list of selected options for single and multi picker
    private String mHint; // value to be shown if mValue is null
    private boolean mRequired; // value to set is the field is required
    private Pair<String, String> checkedAndNotCheckValue = new Pair<>("true", "false");
    private FormAssistantCallback formAssistantCallback;
    private int assistantButtonResId = R.drawable.fm_ic_assistant_button;
    private List<String> filterKeys =  null;

    public FormElement() {
    }

    /**
     * static method to create instance
     *
     * @return
     */
    public static FormElement createInstance() {
        return new FormElement();
    }

    public interface FormAssistantCallback {
        void onAssistantButtonClick(EditText valueEditText);
    }

    // getters and setters
    public FormElement setTag(int mTag) {
        this.mTag = mTag;
        return this;
    }

    public FormElement setType(int mType) {
        this.mType = mType;
        return this;
    }

    public FormElement setTitle(String mTitle) {
        this.mTitle = mTitle;
        return this;
    }

    public FormElement setValue(String mValue) {
        this.mValue = mValue;
        return this;
    }

    public void setSpecifiedValue(Object mSpecifiedValue) {
        this.mSpecifiedValue = mSpecifiedValue;
    }

    public FormElement setHint(String mHint) {
        this.mHint = mHint;
        return this;
    }

    public FormElement setRequired(boolean required) {
        this.mRequired = required;
        return this;
    }

    public FormElement setOptions(List<String> mOptions) {
        this.mOptions = mOptions;
        return this;
    }

    public FormElement setOptionsSelected(List<String> mOptionsSelected) {
        this.mOptionsSelected = mOptionsSelected;
        return this;
    }

    public FormElement setCheckedAndNotCheckValue(Pair<String, String> checkedAndNotCheckValue) {
        this.checkedAndNotCheckValue = checkedAndNotCheckValue;
        return this;
    }

    public FormElement setFormAssistantCallback(FormAssistantCallback formAssistantCallback) {
        this.formAssistantCallback = formAssistantCallback;
        return this;
    }

    public FormElement setAssistantButtonResId(int assistantButtonResId) {
        this.assistantButtonResId = assistantButtonResId;
        return this;
    }

    public FormElement setSpecifiedValues(List<Object> mSpecifiedValues) {
        this.mSpecifiedValues = mSpecifiedValues;
        return this;
    }

    public FormElement setFilterKeys(List<String> filterKeys) {
        this.filterKeys = filterKeys;
        return this;
    }

    public int getTag() {
        return this.mTag;
    }

    public int getType() {
        return this.mType;
    }

    public String getTitle() {
        return this.mTitle;
    }

    public String getValue() {
        return (this.mValue == null) ? "" : this.mValue;
    }

    public Object getSpecifiedValue() {
        int indexOfValue = indexOfValue();
        if (indexOfValue >= 0 && mSpecifiedValues != null) {
            return mSpecifiedValues.get(indexOfValue);
        } else return null;
    }

    public long getDateInMillis() {
        if (TextUtils.isEmpty(mValue)) {
            return 0;
        } else {
            try {
                SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
                return sdfDate.parse(mValue).getTime();
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    }

    public long getTimeInMillis() {
        if (TextUtils.isEmpty(mValue)) {
            return 0;
        } else {
            try {
                SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm", Locale.US);
                return sdfDate.parse(mValue).getTime();
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    }

    public long getDateTimeInMillis() {
        if (TextUtils.isEmpty(mValue)) {
            return 0;
        } else {
            try {
                SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
                return sdfDate.parse(mValue).getTime();
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    }

    public String getHint() {
        return (this.mHint == null) ? "" : this.mHint;
    }

    public boolean isRequired() {
        return this.mRequired;
    }

    public List<String> getOptions() {
        return (this.mOptions == null) ? new ArrayList<String>() : this.mOptions;
    }

    public List<String> getOptionsSelected() {
        return (this.mOptionsSelected == null) ? new ArrayList<String>() : this.mOptionsSelected;
    }

    public Pair<String, String> getCheckedAndNotCheckValue() {
        return checkedAndNotCheckValue;
    }

    public FormAssistantCallback getFormAssistantCallback() {
        return formAssistantCallback;
    }

    public int getAssistantButtonResId() {
        return assistantButtonResId;
    }

    public List<Object> getSpecifiedValues() {
        return mSpecifiedValues;
    }

    public List<String> getFilterKeys() {
        return filterKeys;
    }

    @Override
    public boolean isHeader() {
        return false;
    }

    @Override
    public String toString() {
        return "TAG: " + String.valueOf(this.mTag) + ", TITLE: " + this.mTitle + ", VALUE: " + this.mValue + ", REQUIRED: " + String.valueOf(this.mRequired);
    }

    private int indexOfValue() {
        if (mValue != null && mOptions != null && mOptions.size() > 0) {
            for (int index = 0; index < mOptions.size(); index++) {
                if (mOptions.get(index).equals(mValue)) return index;
            }
        }
        return -1;
    }

}
